/**
 *	@project:	kybernetes
 *	@author:	D.Toepel
 *	@note:		---
 *	
 *	Copyright (C) 2009  D.Toepel <de.dtools> {at} <gmail> {dot} <com>
 *	
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *	
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *	
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *	
 */
package dt.htwk.extras;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import dt.htwk.res.Resource;
import dt.htwk.sql.DBResult;
import dt.htwk.sql.Database;
import dt.htwk.utilities.ButtonCellEditor;
import dt.htwk.utilities.ButtonCellRenderer;
import dt.htwk.utilities.EditTableModel;
import dt.htwk.utilities.TextFieldCellEditor;
import dt.htwk.utilities.TextFieldCellRenderer;

/**
 * <h3>WeatherSimulation</h3>
 *
 * @author DToepel
 * 
 */
public class WeatherSimulation extends JPanel {
	
/* ****************************************************
 * Deklaration der Variablen und Komponenten
 * ***************************************************/
	
	private final boolean DEBUG = false;

	/**
	 * serialVersionUID -- Standard: 1L
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * 
	 */
	private static Hashtable<String, String> lng;
	
	/**
	 * 
	 */
	private static Boolean loggedIn = false;
	
	/*
	 * Komponenten, Variablen und Klassen fuer Wind und GPS-Simulation
	 */
	private static JToggleButton btnSim;
	private static JTextArea simOutput;
	private static SimulationThread sim;
	private JTextField direction;
	private JTextField strength;
	private static JTable windTable;
	private DefaultTableModel windTableModel;

	private JLabel rose;

	private boolean canUpdate = true;

	private DefaultTableModel tableModel;

	private JTable prefTable;

	private JButton btnLoad;

	private JButton btnExport;

	private JButton btnDelete;

	private JRadioButton rbSingel;

	private JRadioButton rbContinuous;

	private JTextField simTime;

	private DefaultTableModel tfTableModel;

	private JTable gpsTable;

	private JButton btnImport;

	private JButton btnSave;

	private JButton btnSaveAs;

	private JButton btnTestConnection;

	private JTextField tfAddress;

	private JTextField tfPort;

	private JLabel statusLabel;

	private JTextArea simDescription;

	private TestServer inst;
	
	private Database db = new Database("weather.sql");
	private DBResult dbResult;
	private WeatherEntry weatherEntry = new WeatherEntry();

	private JCheckBox cbSendGPS;

	private JCheckBox cbSelectAll;
	

/* ****************************************************
 * Aufruf des Konstruktors
 * ***************************************************/

	/**
	 * @param lng
	 */
	public WeatherSimulation(Hashtable<String, String> lng){
	 
		
		super(new BorderLayout());
		WeatherSimulation.lng = lng;
		
		String dbURL = Resource.getCurrPath()+
			System.getProperty("file.separator") + "data" +
			System.getProperty("file.separator") + "simulation" +
			System.getProperty("file.separator") + 	"weather";
		db.setDbData(new Object[]{dbURL,"WEATHER","root",new char[]{'g','e','h','e','i','m'}});
		dbResult = db.setConnection();
		
		initGUI();
		setSimTable();
		
		sim = new SimulationThread();
	}
	
/* ****************************************************
 * PUBLIC - oeffentliche Methoden
 * ***************************************************/

	/**
	 * <h3>setMessage</h3>
	 *
	 * @param msg
	 */
	public static void setMessage(String msg){
		simOutput.append(msg);
		simOutput.setCaretPosition(simOutput.getDocument().getLength());		
	}
	
	/**
	 * <h3>setMessageClear</h3>
	 *
	 * @param msg
	 */
	public static void setMessageClear(){
		simOutput.setText("");
	}
	
	/**
	 * <h3>setDefaultSimButton</h3>
	 *
	 */
	public static void setDefaultSimButton(){
		btnSim.setText(lng.get("tp-sim-btn1"));
		btnSim.setBackground(Resource.darkGreen);
		btnSim.setSelected(false);
	}
	

/* ****************************************************
 * PRIVATE - nicht-oeffentliche Methoden
 * ***************************************************/

	/**
	 * <h3>getTitledPanel</h3>
	 *
	 * @param titel
	 * @return
	 */
	private JPanel getTitledPanel(String titel, LayoutManager layout){
		JPanel labelPanel = new JPanel(layout);
		labelPanel.setOpaque(false);
		labelPanel.setBorder(BorderFactory.createTitledBorder(
				BorderFactory.createLineBorder(new java.awt.Color(110,110,110)), 
				" "+ titel + " ", TitledBorder.LEFT , TitledBorder.TOP,
				new java.awt.Font("Verdana",1,12), Resource.darkMarineBlue));
		labelPanel.setPreferredSize(new Dimension(100,20));
		return labelPanel;
	}


	/**
	 * <h3>initGUI</h3>
	 *
	 * @return
	 */
	private void initGUI() {
			
			// header
			JPanel header = new JPanel(new BorderLayout());
			header.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
			{
				JPanel box;
				JLabel label;
				box = new JPanel();//new BorderLayout());
//				box.setLayout(new BoxLayout(box, BoxLayout.LINE_AXIS));
				{
					btnSim = new JToggleButton();
					btnSim.setFont(new java.awt.Font("Verdana", 1, 12));
					btnSim.setBackground(Resource.darkGreen);
					btnSim.setPreferredSize(new Dimension(170, 35));
					btnSim.setText(lng.get("tp-sim-btn1"));
					btnSim.addActionListener(new ActionListener() {
						
						@Override
						public void actionPerformed(ActionEvent arg0) {
							btnSim_clicked(arg0);
						}
					});
					box.add(btnSim);
					
					JButton btnTestServer = new JButton();
					btnTestServer.setText(lng.get("tp-sim-btn3"));
					btnTestServer.setAlignmentY(TOP_ALIGNMENT);
					btnTestServer.setVerticalAlignment(SwingConstants.TOP);
					btnTestServer.addActionListener(new ActionListener() {
						
						@Override
						public void actionPerformed(ActionEvent arg0) {
							btnTestServer_clicked(arg0);
						}
					});
					box.add(btnTestServer);
				}
				
				header.add(box, BorderLayout.WEST);
				
				box = new JPanel(new BorderLayout());
				label = new JLabel(lng.get("tp-sim"));
				label.setFont(new java.awt.Font("Verdana", 1, 16));
				box.add(label, BorderLayout.PAGE_START);
				label = new JLabel("Kybernetes Cup  -  HTWK Leipzig");
				label.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
				label.setHorizontalAlignment(SwingConstants.RIGHT);
				box.add(label, BorderLayout.PAGE_END);
				header.add(box, BorderLayout.EAST);
				
				this.add(header, BorderLayout.PAGE_START);
			}
			
			JTabbedPane tabbedPane = new JTabbedPane();
			{
				JPanel tab;
				
				// Hinweise
				tab = new JPanel(new BorderLayout());
				{				
					JScrollPane sp = new JScrollPane();
					sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
					
					JLabel notesLabel = new JLabel("<html>" + lng.get("tp-sim-notes") + "</html>");
					{
						notesLabel.setFont(new java.awt.Font("Verdana", 0, 12));
						notesLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
						tab.add(sp.add(notesLabel), BorderLayout.PAGE_START);
					}
				}
				tabbedPane.addTab(lng.get("tp-sim-tab1"), tab);
				
				// Einstellungen
				tab = new JPanel(new BorderLayout());
				tab.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
				{
					JPanel panel;
					
					panel = getTitledPanel(lng.get("tp-sim-sp1"), new GridBagLayout());
//					panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 300));
//					panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
					{
						JPanel editPanel;
						GridBagConstraints g = new GridBagConstraints();
						GridBagConstraints b = new GridBagConstraints();
						GridBagConstraints c = new GridBagConstraints();
							
						editPanel = getTitledPanel(lng.get("tp-sim-sp1-10"), new GridBagLayout());
						editPanel.setPreferredSize(new Dimension(250, 130));
						editPanel.setMaximumSize(new Dimension(250, 130));
						editPanel.setMinimumSize(new Dimension(250, 130));
						{
							rbSingel = new JRadioButton(lng.get("tp-sim-sp1-11"));
							rbSingel.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
							rbSingel.setSelected(true);
							{
								c.gridx = 0;
								c.gridy = 0;
								c.fill = GridBagConstraints.HORIZONTAL;
								c.weightx = 1;
								c.gridwidth = 2;
								editPanel.add(rbSingel, c);
							}
							
							
							rbContinuous = new JRadioButton(lng.get("tp-sim-sp1-12"));
							rbContinuous.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
							{
								c.gridy = 1;
								editPanel.add(rbContinuous, c);
							}
							
							ButtonGroup bg = new ButtonGroup();
							bg.add(rbSingel);
							bg.add(rbContinuous);
							
							c.gridy = 3;
							JLabel label = new JLabel(lng.get("tp-sim-sp1-13"));
							label.setBorder(BorderFactory.createEmptyBorder(2,8,2,8));
							editPanel.add(label, c);
							
							c.gridy = 4;
							c.gridx = 1;
							c.gridwidth = 1;
							c.weightx = 1;
							c.fill = GridBagConstraints.HORIZONTAL;
							simTime = new JTextField("1.5");
							editPanel.add(simTime, c);
							
							c.gridx = 0;
							c.weightx = 0;
							c.anchor = GridBagConstraints.WEST;
							label = new JLabel(lng.get("tp-sim-sp1-14"));
							label.setBorder(BorderFactory.createEmptyBorder(2,8,2,8));
							editPanel.add(label, c);
							
							c.gridy = 2;
							c.weighty = 1;
							c.fill = GridBagConstraints.BOTH;
							editPanel.add(new JLabel(), c);
							
							b.gridx = 0;
							b.gridy = 0;
							panel.add(editPanel, b);
						}
						
						// Routereinstellungen
						editPanel = getTitledPanel(lng.get("tp-sim-sp1-20"), new GridBagLayout());
						editPanel.setPreferredSize(new Dimension(250, 130));
						editPanel.setMaximumSize(new Dimension(250, 130));
						editPanel.setMinimumSize(new Dimension(250, 130));
						{
							JLabel label;
							
							label = new JLabel(lng.get("tp-sim-sp1-21") + " :");
							label.setBorder(BorderFactory.createEmptyBorder(2,8,2,8));
							{
								g.fill = GridBagConstraints.HORIZONTAL;
								editPanel.add(label, g);
							}
							
							label = new JLabel(lng.get("tp-sim-sp1-22") + " :");
							label.setHorizontalTextPosition(SwingConstants.RIGHT);
							label.setBorder(BorderFactory.createEmptyBorder(2,8,2,8));
							{
								g.gridy = 1;
								editPanel.add(label, g);
							}
							
							tfAddress = new JTextField("127.0.0.1");
							{
								g.gridx = 1;
								g.gridy = 0;
								g.weightx = 1;
								
								editPanel.add(tfAddress, g);
							}
							
							tfPort = new JTextField("18098");
							{
								g.gridy = 1;
								editPanel.add(tfPort, g);
							}
							
							btnTestConnection = new JButton(lng.get("tp-sim-sp1-23"));
							btnTestConnection.addActionListener(new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
									testConnection(e);
								}
							});
							{
								g.gridx = 1;
								g.gridy = 3;
								g.weightx = 1;
								
								editPanel.add(btnTestConnection, g);
							}
							
							statusLabel = new JLabel(" ");
							statusLabel.setPreferredSize(new Dimension(22,22));
							statusLabel.setOpaque(true);
							statusLabel.setBackground(Resource.lightMarineBlue);
							statusLabel.setBorder(BorderFactory.createEmptyBorder(2,8,2,8));
							{
								g.gridx = 0;
								g.fill = GridBagConstraints.NONE;
								g.weightx = 0;
								editPanel.add(statusLabel, g);
							}
							
							g.gridy = 2;
							g.weighty = 1;
							g.fill = GridBagConstraints.BOTH;
							editPanel.add(new JLabel(), g);
							
							b.gridx = 1;
							b.gridy = 0;
							panel.add(editPanel, b);
						}
						
						// Beschreibung
						editPanel = getTitledPanel(lng.get("tp-sim-sp1-30"), new BorderLayout());
						editPanel.setPreferredSize(new Dimension(300, 130));
						editPanel.setMaximumSize(new Dimension(300, 130));
						editPanel.setMinimumSize(new Dimension(300, 130));
						{
							simDescription = new JTextArea();
							simDescription.setLineWrap(true);
							editPanel.add(new JScrollPane(
									simDescription, 
									JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
									JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
							b.gridx = 2;
							b.gridy = 0;
							b.fill = GridBagConstraints.HORIZONTAL;
							b.weightx = 1;
							panel.add(editPanel, b);
						}
						
						prefTable = new JTable();
						{
							
							tableModel = new EditTableModel(
									new Object[][]{},	// Tabelle ohne Daten anlegn
							        new Object[]{		// Spaltennamen festlegen
											" ",
											lng.get("tp-sim-sp1-tbl-01"),	// ID
											lng.get("tp-sim-sp1-tbl-02"),	// Zeitstempel
											lng.get("tp-sim-sp1-tbl-03"),	// Beschreibung
											" "," "," ", " "
											},
									new Boolean[]{true,false,false,false,true,true,true,true});
							prefTable.setModel(tableModel);
							
							// Tabelleneigenschaften festlegen
							
							Integer colPrefID = 1;
							
							prefTable.setRowHeight(25);
							prefTable.setDefaultEditor(JButton.class, new ButtonCellEditor(colPrefID));
							prefTable.setDefaultRenderer(JButton.class, new ButtonCellRenderer());
							prefTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
							prefTable.setFillsViewportHeight(true);
							prefTable.setAutoCreateRowSorter(true);
							prefTable.setShowGrid(false);
							
							// Spaltenbreite festlegen
							
							int[] colWidth = new int[]{25, 60, 150, 0, 25, 25, 25, 25};
							for (int i = 0; i < colWidth.length; i++) {
								if (i != 3) {
									prefTable.getTableHeader().getColumnModel().getColumn(i).setMaxWidth(colWidth[i]);
									prefTable.getTableHeader().getColumnModel().getColumn(i).setMinWidth(colWidth[i]);
								}
							}
							
							// Events bei Zeilenauswahl
							
							ListSelectionModel lsm = prefTable.getSelectionModel();
							lsm.addListSelectionListener(new ListSelectionListener() {
								
								@Override
								public void valueChanged(ListSelectionEvent arg0) {
									getSelectedPrefID(arg0);
								}
							});
							
							
							// Position der Tabelle festlegen
							
							b.gridx = 0;
							b.gridy = 1;
							b.gridwidth = 4;
							b.fill = GridBagConstraints.BOTH;
							b.weighty = 1;
							panel.add(new JScrollPane(prefTable), b);
							
							// Testweise Zeilen anlegen
							if (DEBUG){
								for (int i = 0; i < 5; i++) {
									createPrefTableRow(String.valueOf(i), "11.09.09", "Beschreibung");
								}
							}
						}
						
						
						JToolBar toolBar = new JToolBar();
						toolBar.setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
						toolBar.setMargin(new Insets(0,0,0,5));
						toolBar.setFloatable(false);
						toolBar.setOpaque(true);
						toolBar.setOrientation(JToolBar.HORIZONTAL);
						{
							cbSelectAll = new JCheckBox("( " + lng.get("tp-sim-sp1-tbl-btnSelAll") + " )");
							cbSelectAll.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
							cbSelectAll.setRequestFocusEnabled(false);
							cbSelectAll.setToolTipText(lng.get("tp-sim-sp1-tbl-btnSelAll-tt"));
							cbSelectAll.addActionListener(new ActionListener() {
					        	public void actionPerformed(ActionEvent evt) {
					        		tableSetSelection(evt);
					        	}
					        });
							toolBar.add(cbSelectAll);
							
							btnExport = new JButton(Resource.exportIcon);
							btnExport.setRequestFocusEnabled(false);
							btnExport.setText(lng.get("tp-sim-sp1-tbl-btnExpAll"));
							btnExport.setToolTipText(lng.get("tp-sim-sp1-tbl-btnExpAll-tt"));
							btnExport.setMargin(new Insets(2,5,2,5));
							btnExport.addActionListener(new ActionListener() {
					        	public void actionPerformed(ActionEvent evt) {
					        		tableAllExport(evt);
					        	}
					        });
							toolBar.add(btnExport);
							
							btnDelete = new JButton(Resource.deleteIcon);
							btnDelete.setRequestFocusEnabled(false);
							btnDelete.setText(lng.get("tp-sim-sp1-tbl-btnDelAll"));
							btnDelete.setToolTipText(lng.get("tp-sim-sp1-tbl-btnDelAll-tt"));
							btnDelete.setMargin(new Insets(2,5,2,5));
							btnDelete.addActionListener(new ActionListener() {
					        	public void actionPerformed(ActionEvent evt) {
					        		tableAllDelete(evt);
					        	}
					        });
							toolBar.add(btnDelete);
							
							toolBar.add(new JSeparator(SwingConstants.VERTICAL ));
														
							btnImport = new JButton(Resource.importIcon);
							btnImport.setRequestFocusEnabled(false);
							btnImport.setText(lng.get("tp-sim-sp1-tbl-btnImport"));
							btnImport.setToolTipText(lng.get("tp-sim-sp1-tbl-btnImport-tt"));
							btnImport.setMargin(new Insets(2,5,2,5));
							btnImport.addActionListener(new ActionListener() {
					        	public void actionPerformed(ActionEvent evt) {
					        		tableImport(evt);
					        	}
					        });
							toolBar.add(btnImport);
							
							btnSave = new JButton(Resource.saveIcon);
							btnSave.setRequestFocusEnabled(false);
							btnSave.setText(lng.get("tp-sim-sp1-tbl-btnNewEntry"));
							btnSave.setToolTipText(lng.get("tp-sim-sp1-tbl-btnNewEntry-tt"));
							btnSave.setMargin(new Insets(2,5,2,5));
							btnSave.addActionListener(new ActionListener() {
					        	public void actionPerformed(ActionEvent evt) {
					        		tableSaveNew(evt);
					        	}
					        });
							toolBar.add(btnSave);
							
							b.gridx = 0;
							b.gridy = 2;
							b.gridwidth = 4;
							b.fill = GridBagConstraints.HORIZONTAL;
							b.weighty = 0;
							b.weightx = 1;
							b.anchor = GridBagConstraints.WEST;
							
							panel.add(toolBar, b);
							
						}

					}
					tab.add(panel, BorderLayout.CENTER);
										
				}
				tabbedPane.addTab(lng.get("tp-sim-tab2"), tab);
				
				// Wind-Daten
				tab = new JPanel(new BorderLayout());
				tab.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
				{
					JPanel panel = getTitledPanel(lng.get("tp-sim-data1"), new BorderLayout());
					{
						JLabel notesLabel = new JLabel("<html>" + lng.get("tp-sim-data1-00") + "</html>");
						{
							notesLabel.setFont(new java.awt.Font("Verdana", 0, 12));
							notesLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
							panel.add(notesLabel, BorderLayout.PAGE_START);
						}
						
						JPanel center = new JPanel();
						center.setLayout(new BoxLayout(center, BoxLayout.LINE_AXIS));
						center.setOpaque(false);
						center.setAlignmentY(TOP_ALIGNMENT);
						{
							rose = new JLabel(Resource.windRose);
							{
								rose.setSize(Resource.windRose.getIconWidth(), Resource.windRose.getIconHeight());
								rose.setAlignmentY(TOP_ALIGNMENT);
								rose.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
								rose.addMouseMotionListener(new MouseMotionListener() {
									
									@Override
									public void mouseMoved(MouseEvent e) {
										rose_MouseMoved(e);
									}
									
									@Override
									public void mouseDragged(MouseEvent e) {}
								});
								
								rose.addMouseListener(new MouseListener() {
									
									@Override
									public void mouseReleased(MouseEvent e) {}
									
									@Override
									public void mousePressed(MouseEvent e) {}
									
									@Override
									public void mouseExited(MouseEvent e) {}
									
									@Override
									public void mouseEntered(MouseEvent e) {}
									
									@Override
									public void mouseClicked(MouseEvent e) {
										rose_MouseClicked(e);
									}
								});

								center.add(rose);
								center.add(Box.createRigidArea(new Dimension(10, 0)));
							}
							
							JPanel form = new JPanel(new GridBagLayout());
							form.setMaximumSize(new Dimension(200, 300));
							form.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
							form.setAlignmentY(TOP_ALIGNMENT);
							{
								GridBagConstraints c = new GridBagConstraints();
								c.fill = GridBagConstraints.NONE;
								c.gridx = 0;
								
								JLabel label;
								
								label = new JLabel(lng.get("tp-sim-data1-02"));
								{
									c.gridy = 0;
									form.add(label, c);
								}
								
								label = new JLabel(lng.get("tp-sim-data1-03"));
								{
									c.gridy = 1;
									form.add(label, c);
								}
								
								strength = new JTextField();
								{
									c.gridx = 1;
									c.gridy = 0;
									c.fill = GridBagConstraints.HORIZONTAL;
									form.add(strength, c);
								}
								
								direction = new JTextField();
								{
									c.gridy = 1;
									form.add(direction, c);
								}
								
								JPanel cmdTable;
								
								cmdTable = getTitledPanel(lng.get("tp-sim-data1-05"), new GridBagLayout());
								cmdTable.setPreferredSize(new Dimension(180, 90));
								{
									c.gridx = 0;
									c.gridy = 3;
									c.gridwidth = 2;
									c.weightx = 1.0;
									c.fill = GridBagConstraints.BOTH;
									form.add(cmdTable, c);
								}
								
								JButton btnAtEnd = new JButton(lng.get("tp-sim-data1-06"));
								btnAtEnd.setMinimumSize(new Dimension(160, 25));
								{
									c.gridy = 0;
									btnAtEnd.addActionListener(new ActionListener() {
										
										@Override
										public void actionPerformed(ActionEvent arg0) {
											btnAtEnd_clicked(arg0);
										}
									});
									cmdTable.add(btnAtEnd, c);
								}
								
								JButton btnAtMark = new JButton(lng.get("tp-sim-data1-07"));
								btnAtMark.setMinimumSize(new Dimension(160, 25));
								{
									c.gridy = 1;
									btnAtMark.addActionListener(new ActionListener() {
										
										@Override
										public void actionPerformed(ActionEvent arg0) {
											btnAtMark_clicked(arg0);
										}
									});
									cmdTable.add(btnAtMark, c);
								}
																
								cmdTable = getTitledPanel(lng.get("tp-sim-data1-08"), new GridBagLayout());
								cmdTable.setPreferredSize(new Dimension(180, 90));
								{
									c.gridy = 5;
									c.gridwidth = 2;
									c.fill = GridBagConstraints.BOTH;
									form.add(cmdTable, c);
								}
								
								JButton btnDelMark = new JButton(lng.get("tp-sim-data1-09"));
								btnDelMark.setMinimumSize(new Dimension(160, 25));
								{
									c.gridy = 0;
									btnDelMark.addActionListener(new ActionListener() {
										
										@Override
										public void actionPerformed(ActionEvent arg0) {
											btnDelMark_clicked(arg0);
										}
									});
									cmdTable.add(btnDelMark, c);
								}
																
								JButton btnDelAll = new JButton(lng.get("tp-sim-data1-10"));
								btnDelAll.setMinimumSize(new Dimension(160, 25));
								{
									c.gridy = 1;
									btnDelAll.addActionListener(new ActionListener() {
										
										@Override
										public void actionPerformed(ActionEvent arg0) {
											btnDelAll_clicked(arg0);
											
										}
									});
									cmdTable.add(btnDelAll, c);
								}
								
								// zum auffuellen
								label = new JLabel();
								{
									c.gridy = 2;
									c.weighty = 0.5;
									c.fill = GridBagConstraints.VERTICAL;
									form.add(label, c);
								}
								
								// zum auffuellen
								label = new JLabel();
								{
									c.gridy = 4;
									form.add(label, c);
								}
								
								center.add(form);
								center.add(Box.createRigidArea(new Dimension(10, 0)));
							}
							
							JPanel tableHolder = new JPanel(new BorderLayout());
							{
								tableHolder.setMaximumSize(new Dimension(Integer.MAX_VALUE, 300));
								tableHolder.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
								tableHolder.setAlignmentY(TOP_ALIGNMENT);
								windTableModel = new DefaultTableModel();
								windTableModel.addColumn(lng.get("tp-sim-data1-02"));
								windTableModel.addColumn(lng.get("tp-sim-data1-03"));
								windTableModel.addColumn(lng.get("tp-sim-data1-04"));
								windTableModel.addTableModelListener(new TableModelListener() {
									
									@Override
									public void tableChanged(TableModelEvent arg0) {
										if (canUpdate)
											updateWindTable();
									}
								});
								windTable = new JTable(windTableModel);
								windTable.setFillsViewportHeight(true);
								windTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
								windTable.setShowGrid(true);
								tableHolder.add(new JScrollPane(windTable), BorderLayout.CENTER);
								center.add(tableHolder);
								center.add(Box.createRigidArea(new Dimension(10, 0)));
							}
							panel.add(center, BorderLayout.LINE_START);
						}
						
						tab.add(panel, BorderLayout.CENTER);
						
					}
				}
				tabbedPane.addTab(lng.get("tp-sim-tab3"), tab);
				
				
				// GPS-Daten
				tab = new JPanel(new BorderLayout());
				tab.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
				{
					JPanel panel = getTitledPanel(lng.get("tp-sim-data2"), new GridBagLayout());
					{
						
						GridBagConstraints c = new GridBagConstraints();
						
						tfTableModel = new EditTableModel(
								new Object[][]{},	// Tabelle ohne Daten anlegn
						        new Object[]{		// Spaltennamen festlegen
										lng.get("tp-sim-data2-tbl-col01"),	// Punkt
										lng.get("tp-sim-data2-tbl-col02"),	// Longitude
										lng.get("tp-sim-data2-tbl-col03"),	// Latitude
										lng.get("tp-sim-data2-tbl-col04")	// Beschreibung
										},
								new Boolean[]{false,true,true,false});
						
						
						gpsTable = new JTable(tfTableModel);
						{
							// Tabelleneigenschaften festlegen
														
							gpsTable.setRowHeight(25);
							gpsTable.setDefaultEditor(JTextField.class, new TextFieldCellEditor());
							gpsTable.setDefaultRenderer(JTextField.class, new TextFieldCellRenderer());
							gpsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
							gpsTable.setFillsViewportHeight(true);
							gpsTable.setAutoCreateRowSorter(true);
							gpsTable.setShowGrid(false);
							
							// Spaltenbreite festlegen
							
							int[] colWidth = new int[]{200, 250, 250};
							for (int i = 0; i < colWidth.length; i++) {
								gpsTable.getTableHeader().getColumnModel().getColumn(i).setMaxWidth(colWidth[i]);
								gpsTable.getTableHeader().getColumnModel().getColumn(i).setMinWidth(colWidth[i]);
							}
							
							// Events bei Zeilenauswahl
							
							ListSelectionModel lsm = gpsTable.getSelectionModel();
							lsm.addListSelectionListener(new ListSelectionListener() {
								
								@Override
								public void valueChanged(ListSelectionEvent arg0) {
									getSelectedPrefID(arg0);
								}
							});
							
							
							// Position der Tabelle festlegen
							
							c.gridx = 1;
							c.weightx = 1;
							c.weighty = 1;
							c.fill = GridBagConstraints.BOTH;
							panel.add(new JScrollPane(gpsTable), c);
							
							// Zeilen anlegen
							for (int i = 0; i < 10; i++) {
								tfTableModel.addRow(new Object[]{lng.get("tp-sim-data2-tbl-gps-" + i), new JTextField("-1"), new JTextField("-1"), ""});
							}
							
							cbSendGPS = new JCheckBox(lng.get("tp-sim-data2-cb"));
							cbSendGPS.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
							cbSendGPS.setSelected(true);
							c.gridy = 1;
							c.weightx = 1;
							c.weighty = 0;
							c.fill = GridBagConstraints.HORIZONTAL;
							panel.add(cbSendGPS, c);
							
							JLabel label = new JLabel("<html>" + lng.get("tp-sim-data2-note") + "</html>");
							label.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
							c.gridy = 2;
							c.weightx = 1;
							c.weighty = 0;
							c.fill = GridBagConstraints.HORIZONTAL;
							panel.add(label, c);
							
							
							JPanel holder = new JPanel();
							holder.setBackground(Resource.white);
							label = new JLabel(Resource.regattaIcon);
							label.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
							holder.add(label);
							c.gridx = 0;
							c.gridy = 0;
							c.weightx = 0;
							c.weighty = 1;
							c.gridheight = 3;
							c.fill = GridBagConstraints.BOTH;
							panel.add(holder, c);
						}
						tab.add(panel, BorderLayout.CENTER);
					}
				}
				tabbedPane.addTab(lng.get("tp-sim-tab4"), tab);
				
				this.add(tabbedPane, BorderLayout.CENTER);
			}
			
			// Footer
			simOutput = new JTextArea();
			simOutput.setEditable(false);
			simOutput.setRows(5);
			this.add(new JScrollPane(simOutput), BorderLayout.PAGE_END);
		
	}

	

/* ****************************************************
 * ACTIONS - Aktionen der einzelnen Komponenten
 * ***************************************************/
	
	/**
	 * <h3>btnSim_clicked</h3>
	 *
	 */
	private void btnSim_clicked(ActionEvent arg0) {
		if (loggedIn){
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-run-text"),
				    lng.get("dlg-sim-run"),
				    JOptionPane.WARNING_MESSAGE);
			setDefaultSimButton();
			return;
		}
		if (btnSim.isSelected()){
			if(getSimData()){
				btnSim.setText(lng.get("tp-sim-btn2"));
				btnSim.setBackground(Resource.darkRed);
				setMessageClear();
				sim.setTable(windTable);
				sim.setWeatherEntry(weatherEntry);
				sim.start();
			}else{
				JOptionPane.showMessageDialog(new JFrame(),
						lng.get("dlg-sim-err-text"),
					    lng.get("dlg-sim-err"),
					    JOptionPane.WARNING_MESSAGE);
				setDefaultSimButton();
			}
		}else{
			setDefaultSimButton();
			sim.stopThread();
		}
	}
	
	/**
	 * <h3>btnTestServer_clicked</h3>
	 *
	 */
	private void btnTestServer_clicked(ActionEvent arg0){
		TestServer.setLanguageContent(lng);
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				if (inst == null){
					inst = new TestServer();
					inst.setLocationRelativeTo(null);
				}
				inst.setVisible(true);
				inst.toFront();
			}
		});
	}
	
	/**
	 * <h3>testConnection</h3>
	 *
	 * @param e
	 */
	private void testConnection(ActionEvent e) {
		setMessageClear();
		try {
			String addr = tfAddress.getText();
			int port = Integer.parseInt(tfPort.getText());
			Socket socket = new Socket(addr, port);
			
			OutputStream os = socket.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os); 
			BufferedWriter out = new BufferedWriter(osw);
			
			out.write("<noop />");
			out.flush();
			out.close();
			socket.close();
			
			statusLabel.setBackground(Resource.darkGreen);
			setMessage("[TEST]>>> <noop />");
			
		} catch (Exception ex) {
			setMessage("[TEST]>>> <noop />\n");
			setMessage("Error while sending socket message: " + ex.getMessage());
			statusLabel.setBackground(Resource.darkRed);
		} 
	}
	
	/**
	 * <h3>getSelectedPrefID</h3>
	 *
	 * @param arg0
	 */
	private void getSelectedPrefID(ListSelectionEvent arg0) {
//		int iRow = prefTable.getSelectedRow();
//		prefID = Integer.parseInt(prefTable.getValueAt(iRow, 0).toString());
	}
	
	/**
	 * <h3>tableSetSelection</h3>
	 *
	 * @param arg0
	 */
	private void tableSetSelection(ActionEvent arg0){
		JCheckBox cb = (JCheckBox) arg0.getSource();
		for (int i = 0; i < prefTable.getRowCount(); i++) {
			prefTable.setValueAt(cb.isSelected(), i, 0);
		}
	}
	
	/**
	 * <h3>tableRowLoad</h3>
	 *
	 * @param arg0
	 */
	private void tableRowLoad(ActionEvent arg0){
		JButton btn = (JButton) arg0.getSource();
		setSimData(Integer.parseInt(btn.getActionCommand()));
	}
	
	/**
	 * <h3>tableRowExport</h3>
	 *
	 * @param arg0
	 */
	private void tableRowExport(ActionEvent arg0){
		JButton btn = (JButton) arg0.getSource();
		
		String fileName = saveDialog();
		if (fileName != null){
			if (!fileName.toLowerCase().endsWith(".xml"))
				fileName += ".xml";
			
			Vector<WeatherEntry> entries = new Vector<WeatherEntry>();
			WeatherEntry entry = db.getSimulationEntry(Integer.parseInt(btn.getActionCommand()));
			entries.add(entry);
			writeXML(fileName, entries);
		}
	}
	
	/**
	 * <h3>tableAllExport</h3>
	 *
	 * @param arg0
	 */
	private void tableAllExport(ActionEvent arg0){
		String fileName = saveDialog();
		if (fileName != null){
			if (!fileName.toLowerCase().endsWith(".xml"))
				fileName += ".xml";
			
			Vector<WeatherEntry> entries = new Vector<WeatherEntry>();
			for (int i = 0; i < tableModel.getRowCount(); i++) {
				Integer idx = Integer.parseInt(tableModel.getValueAt(i, 1).toString());
				Boolean canExport = Boolean.parseBoolean(tableModel.getValueAt(i, 0).toString());
				if(canExport){
					WeatherEntry entry = db.getSimulationEntry(idx);
					entries.add(entry);
				}
			}
			
			writeXML(fileName, entries);
		}
		
		setSimTable();
	}

	/**
	 * <h3>tableRowDelete</h3>
	 *
	 * @param arg0
	 */
	private void tableRowDelete(ActionEvent arg0){
		JButton btn = (JButton) arg0.getSource();
		dbResult = db.deleteEntry(Integer.parseInt(btn.getActionCommand()));
		setSimTable();
	}
	
	/**
	 * <h3>tableAllDelete</h3>
	 *
	 * @param arg0
	 */
	private void tableAllDelete(ActionEvent arg0){
		for (int i = 0; i < tableModel.getRowCount(); i++) {
			Integer idx = Integer.parseInt(tableModel.getValueAt(i, 1).toString());
			Boolean canDelete = Boolean.parseBoolean(tableModel.getValueAt(i, 0).toString());
			if(canDelete){
				dbResult = db.deleteEntry(idx);
			}
		}
		setSimTable();
	}
	
	/**
	 * <h3>tableRowSave</h3>
	 *
	 * @param arg0
	 */
	private void tableRowSave(ActionEvent arg0){
		JButton btn = (JButton) arg0.getSource();
		if(getSimData()){
			weatherEntry.setEntryID(Integer.parseInt(btn.getActionCommand()));
			dbResult = db.setSimulationData(weatherEntry);
			setSimTable();
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-save-ok"),
				    lng.get("dlg-sim-save"),
				    JOptionPane.INFORMATION_MESSAGE);
		}else{
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-save-err"),
				    lng.get("dlg-sim-save"),
				    JOptionPane.WARNING_MESSAGE);
			setDefaultSimButton();
		}
	}
	
	/**
	 * <h3>tableSaveNew</h3>
	 *
	 * @param arg0
	 */
	private void tableSaveNew(ActionEvent arg0){
		if(getSimData()){
			weatherEntry.setEntryID(null);
			dbResult = db.setSimulationData(weatherEntry);
			setSimTable();
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-save-ok"),
				    lng.get("dlg-sim-save"),
				    JOptionPane.INFORMATION_MESSAGE);
		}else{
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-save-err"),
				    lng.get("dlg-sim-save"),
				    JOptionPane.WARNING_MESSAGE);
			setDefaultSimButton();
		}
	}
	
	/**
	 * <h3>tableImport</h3>
	 *
	 * @param arg0
	 */
	private void tableImport(ActionEvent arg0){
		String fileName = openDialog();
		if (fileName != null)
			readXML(fileName);
	}
	
	/**
	 * <h3>rose_MouseMoved</h3>
	 *
	 * @param e
	 */
	private void rose_MouseMoved(MouseEvent e) {
		Integer[] ergebnis = berechnung(e.getX(), e.getY());
		rose.setToolTipText(
				"<html><span style=\"font-weight:bold;\">" + lng.get("tp-sim-data1-01") + "</span><hr>" +
				lng.get("tp-sim-data1-02") + ": " + ergebnis[1] + 
				"<br>" + lng.get("tp-sim-data1-03") + ": " + ergebnis[0] + "</html>");
	}

	/**
	 * <h3>rose_MouseClicked</h3>
	 *
	 * @param e
	 */
	private void rose_MouseClicked(MouseEvent e) {
		if (e.getClickCount() == 1){
			Integer[] ergebnis = berechnung(e.getX(), e.getY());
			strength.setText(ergebnis[1].toString());
			direction.setText(ergebnis[0].toString());
		}
	}


	/**
	 * <h3>btnAtEnd_clicked</h3>
	 *
	 * @param arg0
	 */
	private void btnAtEnd_clicked(ActionEvent arg0) {
		int lenStrength = strength.getText().trim().length();
		int lenDirection = direction.getText().trim().length();
		
		if (lenStrength > 0 && lenDirection > 0){
			windTableModel.addRow(new Object[]{strength.getText(),direction.getText()});
		}else{
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-input-err-text"),
				    lng.get("dlg-input-err"),
				    JOptionPane.WARNING_MESSAGE);
		}
	}

	/**
	 * <h3>btnAtMark_clicked</h3>
	 *
	 * @param arg0
	 */
	private void btnAtMark_clicked(ActionEvent arg0) {
		if (windTable.getSelectedRow() > -1){
			windTableModel.setValueAt(strength.getText(), windTable.getSelectedRow(), 0);
			windTableModel.setValueAt(direction.getText(), windTable.getSelectedRow(), 1);
		}else{
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-table-err-text"),
					lng.get("dlg-table-err"),
				    JOptionPane.WARNING_MESSAGE);
		}
	}
	
	/**
	 * <h3>btnDelMark_clicked</h3>
	 *
	 * @param arg0
	 */
	private void btnDelMark_clicked(ActionEvent arg0) {
		if(windTable.getSelectedRow() > -1){
			windTableModel.removeRow(windTable.getSelectedRow());
		}else{
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-table-del-text"),
				    lng.get("dlg-table-del"),
				    JOptionPane.WARNING_MESSAGE);
		}
	}

	/**
	 * <h3>btnDelAll_clicked</h3>
	 *
	 * @param arg0
	 */
	private void btnDelAll_clicked(ActionEvent arg0) {
		while(windTable.getRowCount() > 0){
			windTableModel.removeRow(0);
		}
	}
	
	/**
	 * <h3>updateWindTable</h3>
	 *
	 */
	private void updateWindTable(){
		// 0 - 16 - 32 - 48 - 64 -> 64 = 90Grad = 4
		canUpdate = false;
    	int rows = windTable.getRowCount();
    	int rowValue, rowOldValue,fluctuation = 0;
		for (int i = 0; i < windTable.getRowCount(); i++) {
			if (rows == 0){
				windTable.setValueAt("0", 0, 2);
			}else{
				if ((String) windTableModel.getValueAt(i, 1) == null) continue;
				
				rowValue = Integer.parseInt((String) windTableModel.getValueAt(i, 1));
				if (i == 0){
					rowOldValue = Integer.parseInt((String) windTableModel.getValueAt(rows - 1, 1));
				}else{
					rowOldValue = Integer.parseInt((String) windTableModel.getValueAt(i - 1, 1));
				}
				
				fluctuation = Math.abs(rowValue - rowOldValue);
				
				if(fluctuation == 0)
					windTableModel.setValueAt("0", i, 2);
				else if(0 < fluctuation && fluctuation <= 16)
					windTableModel.setValueAt("1", i, 2);
				else if(16 < fluctuation && fluctuation <= 32)
					windTableModel.setValueAt("2", i, 2);
				else if(32 < fluctuation && fluctuation <= 64)
					windTableModel.setValueAt("3", i, 2);
				else if(64 < fluctuation)
					windTableModel.setValueAt("4", i, 2);
			}
			
		}
		canUpdate = true;
	}



/* ****************************************************
 * FUNCTIONS - zusaetzlich Funktionen
 * ***************************************************/
	
	/**
	 * <h3>createPrefTableRow</h3>
	 *
	 * @param string
	 * @param string2
	 * @param string3
	 */
	private void createPrefTableRow(String id, String time, String description) {
		
		// Schaltflaechen fuer Tabellen erstellen
		btnLoad = new JButton(Resource.loadIcon);
		btnLoad.setRequestFocusEnabled(false);
		btnLoad.setMargin(new Insets(1,1,1,1));
		btnLoad.setToolTipText(lng.get("tp-sim-sp1-tbl-btnLoadRow-tt"));
		btnLoad.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent evt) {
        		tableRowLoad(evt);
        	}
        });
		
		btnSaveAs = new JButton(Resource.saveAsIcon);
		btnSaveAs.setRequestFocusEnabled(false);
		btnSaveAs.setMargin(new Insets(1,1,1,1));
		btnSaveAs.setToolTipText(lng.get("tp-sim-sp1-tbl-btnSaveRow-tt"));
		btnSaveAs.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent evt) {
        		tableRowSave(evt);
        	}
        });
		

		btnExport = new JButton(Resource.exportIcon);
		btnExport.setRequestFocusEnabled(false);
		btnExport.setMargin(new Insets(1,1,1,1));
		btnExport.setToolTipText(lng.get("tp-sim-sp1-tbl-btnExpRow-tt"));
		btnExport.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent evt) {
        		tableRowExport(evt);
        	}
        });
		
		btnDelete = new JButton(Resource.deleteIcon);
		btnDelete.setRequestFocusEnabled(false);
		btnDelete.setMargin(new Insets(1,1,1,1));
		btnDelete.setToolTipText(lng.get("tp-sim-sp1-tbl-btnDelRow-tt"));
		btnDelete.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent evt) {
        		tableRowDelete(evt);
        	}
        });
		
		
		tableModel.addRow(new Object[]{new Boolean(false), id, time, description, btnLoad, btnSaveAs, btnExport, btnDelete});
		
	}

	
	/**
	 * <h3>setSimTable</h3>
	 *
	 */
	private void setSimTable(){
		
		while (tableModel.getRowCount() > 0) {
			tableModel.removeRow(0);
		}
		
		if(dbResult.getRowCount() > 0){
			String[][] result = dbResult.getRowContent();
			
			for (int i = 0; i < result.length; i++) {
				createPrefTableRow(result[i][0],result[i][1],result[i][2]);
			}
		}
		cbSelectAll.setSelected(false);
	}
	
	
	/**
	 * <h3>getSimData</h3>
	 *
	 * @return
	 */
	private Boolean getSimData(){
		
		if(windTable.getRowCount() < 1){
			return false;
		}else{
			String[][] windData = new String[windTable.getRowCount()][3];
			Double[][] gpsData = new Double[gpsTable.getRowCount()][2];
			
			for (int i = 0; i < windTable.getRowCount(); i++) {
				windData[i][0] = (String) windTable.getValueAt(i, 0);
				windData[i][1] = (String) windTable.getValueAt(i, 1);
				windData[i][2] = (String) windTable.getValueAt(i, 2);
			}
			
			for (int i = 0; i < gpsTable.getRowCount(); i++) {
				String lon = ((JTextField)gpsTable.getValueAt(i, 1)).getText();
				String lat = ((JTextField)gpsTable.getValueAt(i, 2)).getText();
				gpsData[i][0] = Double.parseDouble(lon.replace(",", "."));
				gpsData[i][1] = Double.parseDouble(lat.replace(",", "."));
			}
			
			weatherEntry.setDescreption(simDescription.getText());
			weatherEntry.setSingleMode(rbSingel.isSelected());
			weatherEntry.setStepTime(Double.parseDouble(simTime.getText().replace(",", ".")));
			weatherEntry.setServerAddress(tfAddress.getText());
			weatherEntry.setServerPort(Integer.parseInt(tfPort.getText()));
			weatherEntry.setSendGpsOnce(cbSendGPS.isSelected());
			weatherEntry.setWindData(windData);
			weatherEntry.setGpsData(gpsData);			
		}
		
		
		
		return true;
	}
	
	private void setSimData(Integer entryID){
		weatherEntry = db.getSimulationEntry(entryID);
		
		String[][] windData = weatherEntry.getWindData();
		Double[][] gpsData = weatherEntry.getGpsData();
		
		while(windTable.getRowCount() > 0){
			windTableModel.removeRow(0);
		}
		
		for (int i = 0; i < windData.length; i++) {
			String[] row = windData[i];
			windTableModel.addRow(row);
		}
		
		for (int i = 0; i < gpsTable.getRowCount(); i++) {
			((JTextField)gpsTable.getValueAt(i, 1)).setText(gpsData[i][0].toString());
			((JTextField)gpsTable.getValueAt(i, 2)).setText(gpsData[i][1].toString());
		}
		
		simDescription.setText(weatherEntry.getDescreption());
		rbSingel.setSelected(weatherEntry.getSingleMode());
		rbContinuous.setSelected(!weatherEntry.getSingleMode());
		simTime.setText(weatherEntry.getStepTime().toString());
		tfAddress.setText(weatherEntry.getServerAddress());
		tfPort.setText(weatherEntry.getServerPort().toString());
		cbSendGPS.setSelected(weatherEntry.getSendGpsOnce());
	}
	
	
    /**<h3>Windparameter berechnen</h3><hr />
     * <p>Die hier berechneten Windparameter beziehen sich
     * auf Werte, die eigentlich vom Windsensor empfangen werden.
     * Das bedeutet, die Windrichtung bzw. Windstaerke
     * kann nur einen Wert zwischen 0-255 annehmen.</p>
     * @param x (Integer)
     * @param y (Integer)
     * @return
     * <ul>
     *  <li>ergebnis[0] - (int) Windrichtung (0-255)</li>
     *  <li>ergebnis[1] - (int) Windstaerke (0-255)</li>
     *  <li>ergebnis[2] - (int) Windaenderung (0-4)</li>
     * </ul>
     */
    private Integer[] berechnung(int x, int y){
        // --- Variablen festlegen
        Integer[] ergebnis = new Integer[3];
        int newX = x - 107;
        int newY = 103 - y;
        double newC = Math.sqrt(Math.pow(newX, 2)+Math.pow(newY, 2));
        int direction = 0;   // zwischen 0 - 255
        int strength = 0;    // zwischen 0 - 255
        int fluctuation = 0; // zwischen 0 - 4
        
        int quadrant = getQuadrant(newX,newY);

        double angleXY;
        // Aufgrund der veraenderten Quadranten, wird der
        // COS(a) mit a = Gegenkathete/Hypotenuse berechnet.
        if (quadrant < 2)
            angleXY = Math.round(Math.acos(newY/newC) * (180/Math.PI));
        else
            angleXY = 360 - Math.round(Math.acos(newY/newC) * (180/Math.PI));
        
        // --- Berechnung der Windrichtung
        direction =  (int) Math.round(angleXY * 255 / 360);

        // --- Berechnung der Windstaerke
        if (newC <= 85)
            strength = (int) Math.round(newC * 255 / 85);//
        else
            strength = 255;

        // --- Ergebnis zurueckgeben
        ergebnis[0] = direction;
        ergebnis[1] = strength;
        ergebnis[2] = fluctuation;
        return ergebnis;
    }

    
    /** <h3>Quadrant ermitteln</h3><hr />
     * <p>Der hier ermittelte Quadrant entspricht nicht dem
     * mathematischen Sinn. Der verwendete Windsensor
     * nimmt den Norden mit 0 Grad an und der Winkel erhoeht
     * sich im Uhrzeigersinn.</p>
     * <pre>
     * 3 | 0
     * -----
     * 2 | 1
     * </pre>
     * @param x (Integer)
     * @param y (Integer)
     * @return Integer zwischen 0-3.
     */
    private Integer getQuadrant(int x, int y){

        int ergebnis = 0;
        
        if (x > 0){
            if (y > 0) ergebnis = 0;
            else if (y <= 0) ergebnis = 1;
        }
        else if (x < 0){
            if (y <= 0) ergebnis = 2;
            else if (y > 0) ergebnis = 3;
        }
        else if (x == 0){
            if (y > 0) ergebnis = 0;
            else if (y < 0) ergebnis = 3;
        }
        return ergebnis;
    }
    
    private String saveDialog(){
    	String fileName = null;
    	final JFileChooser fc = new JFileChooser();
    	fc.setAcceptAllFileFilterUsed(false);
    	fc.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {
			
			@Override
			public String getDescription() {
				return "XML | *.xml";
			}
			
			@Override
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
			}
		});
    	fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    	fc.setMultiSelectionEnabled(false);
    	fc.setCurrentDirectory(new File(Resource.getCurrPath()));

    	int returnVal = fc.showSaveDialog(WeatherSimulation.this);
    	
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            try {
            	fileName = file.getCanonicalPath();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
    	return fileName;
    }
    
    private String openDialog(){
    	String fileName = null;
    	final JFileChooser fc = new JFileChooser();
    	fc.setAcceptAllFileFilterUsed(false);
    	fc.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {
			
			@Override
			public String getDescription() {
				return "XML | *.xml";
			}
			
			@Override
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
			}
		});
    	fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    	fc.setMultiSelectionEnabled(false);
    	fc.setCurrentDirectory(new File(Resource.getCurrPath()));

    	int returnVal = fc.showOpenDialog(WeatherSimulation.this);
    	
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            try {
            	fileName = file.getCanonicalPath();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
    	return fileName;
    }

    private void readXML(String filename){
    	try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder dbu = dbf.newDocumentBuilder();
			Document dom = dbu.parse (new File(filename));
			Element domElement = dom.getDocumentElement();
			
			NodeList entryList = domElement.getElementsByTagName("entry");
	        Integer counter = entryList.getLength();
	        
    		WeatherEntry tempEntry;
    		WeatherEntry[] entries = new WeatherEntry[counter];

	        for (int i = 0; i < counter; i++) {
	        	tempEntry = new WeatherEntry();
	        	Node entry = entryList.item(i);
	        	Element entryElement = (Element)entry;
				NodeList setList = entryElement.getElementsByTagName("settings");
				{
					Element settings = (Element)setList.item(0);
					tempEntry.setSingleMode(Boolean.parseBoolean(settings.getAttribute("smode")));
					tempEntry.setStepTime(Double.parseDouble(settings.getAttribute("stime")));
					tempEntry.setSendGpsOnce(Boolean.parseBoolean(settings.getAttribute("sendgps")));
				}
				NodeList serverList = entryElement.getElementsByTagName("server");
				{
					Element server = (Element)serverList.item(0);
					tempEntry.setServerAddress(server.getAttribute("addr"));
					tempEntry.setServerPort(Integer.parseInt(server.getAttribute("port")));
				}
				NodeList descList = entryElement.getElementsByTagName("description");
				{
					Element description = (Element)descList.item(0);
					tempEntry.setDescreption(description.getTextContent());
				}
				NodeList gpsList = entryElement.getElementsByTagName("gpsdata");
				{
					Node gps = gpsList.item(0);
		        	Element gpsElement = (Element)gps;
		        	Double[][] gpsdata = new Double[10][2];
		        	gpsdata[0][0] = Double.parseDouble(gpsElement.getAttribute("longBase"));
		        	gpsdata[0][1] = Double.parseDouble(gpsElement.getAttribute("latBase"));
		        	
					NodeList luv = gpsElement.getElementsByTagName("luv");
					{
						Element el = (Element)luv.item(0);
						gpsdata[1][0] = Double.parseDouble(el.getAttribute("long1"));
			        	gpsdata[1][1] = Double.parseDouble(el.getAttribute("lat1"));
					}
					NodeList lee = gpsElement.getElementsByTagName("lee");
					{
						Element el = (Element)lee.item(0);
						gpsdata[2][0] = Double.parseDouble(el.getAttribute("long1"));
			        	gpsdata[2][1] = Double.parseDouble(el.getAttribute("lat1"));
			        	gpsdata[3][0] = Double.parseDouble(el.getAttribute("long2"));
			        	gpsdata[3][1] = Double.parseDouble(el.getAttribute("lat2"));
					}
					NodeList lne = gpsElement.getElementsByTagName("finishLine");
					{
						Element el = (Element)lne.item(0);
						gpsdata[4][0] = Double.parseDouble(el.getAttribute("long1"));
			        	gpsdata[4][1] = Double.parseDouble(el.getAttribute("lat1"));
			        	gpsdata[5][0] = Double.parseDouble(el.getAttribute("long2"));
			        	gpsdata[5][1] = Double.parseDouble(el.getAttribute("lat2"));
					}
					NodeList box = gpsElement.getElementsByTagName("startBox");
					{
						Element el = (Element)box.item(0);
						gpsdata[6][0] = Double.parseDouble(el.getAttribute("long1"));
			        	gpsdata[6][1] = Double.parseDouble(el.getAttribute("lat1"));
			        	gpsdata[7][0] = Double.parseDouble(el.getAttribute("long2"));
			        	gpsdata[7][1] = Double.parseDouble(el.getAttribute("lat2"));
			        	gpsdata[8][0] = Double.parseDouble(el.getAttribute("long3"));
			        	gpsdata[8][1] = Double.parseDouble(el.getAttribute("lat3"));
			        	gpsdata[9][0] = Double.parseDouble(el.getAttribute("long4"));
			        	gpsdata[9][1] = Double.parseDouble(el.getAttribute("lat4"));
					}
					tempEntry.setGpsData(gpsdata);
				}
				NodeList windList = entryElement.getElementsByTagName("winddata");
				{
					Node wind = windList.item(0);
		        	Element windElement = (Element)wind;
					NodeList list = windElement.getElementsByTagName("wind");
					String[][] winddata = new String[list.getLength()][3];
					for (int j = 0; j < list.getLength(); j++) {
						Element row = (Element)list.item(j);
						winddata[j][0] = row.getAttribute("strength");
						winddata[j][1] = row.getAttribute("direction");
						winddata[j][2] = row.getAttribute("fluctuation");
					}
					tempEntry.setWindData(winddata);
				}
				
				entries[i] = tempEntry;
				
				tempEntry.setEntryID(null);
				dbResult = db.setSimulationData(tempEntry);
				setSimTable();
			}
	        
	        JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-import-ok"),
				    lng.get("dlg-sim-import"),
				    JOptionPane.INFORMATION_MESSAGE);
	        
		} catch (ParserConfigurationException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-import-err") + "\n\nError: [ParserConfigurationException] " + e.getMessage(),
				    lng.get("dlg-sim-import"),
				    JOptionPane.WARNING_MESSAGE);
		} catch (SAXException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-import-err") + "\n\nError [SAXException] : " + e.getMessage(),
				    lng.get("dlg-sim-import"),
				    JOptionPane.WARNING_MESSAGE);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-import-err") + "\n\nError [IOException] : " + e.getMessage(),
				    lng.get("dlg-sim-import"),
				    JOptionPane.WARNING_MESSAGE);
		}catch (Exception e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-import-err") + "\n\nError: " + e.toString(),
				    lng.get("dlg-sim-import"),
				    JOptionPane.WARNING_MESSAGE);
		}
		
    }

    private void writeXML(String filename, Vector<WeatherEntry> entries){
    	//
    	try
		{
    		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    		DocumentBuilder dbu = dbf.newDocumentBuilder();
    		Document dom = dbu.newDocument();
    		
    		Element rootElement = dom.createElement("simdata");
    		dom.appendChild(rootElement);
        	
    		for (int i = 0; i < entries.size(); i++) {
    			WeatherEntry weather = entries.elementAt(i);
    			Element entry = dom.createElement("entry");
    			{
    				rootElement.appendChild(entry);
    				entry.setAttribute("id", weather.getEntryID().toString());
    				entry.setAttribute("time", weather.getTimestamp().toString());
    			}
    			
    			Element settings = dom.createElement("settings");
    			{
    				entry.appendChild(settings);
    				settings.setAttribute("smode", weather.getSingleMode().toString());
    				settings.setAttribute("stime", weather.getStepTime().toString());
    				settings.setAttribute("sendgps", weather.getSendGpsOnce().toString());
    				settings.normalize();
    			}
    			
    			Element description = dom.createElement("description");
    			{
	    			entry.appendChild(description);
	    			description.appendChild(dom.createTextNode(weather.getDescreption()));
	    			description.normalize();
    			}
    			
    			Element server = dom.createElement("server");
    			{
    				entry.appendChild(server);
    				server.setAttribute("addr", weather.getServerAddress());
    				server.setAttribute("port", weather.getServerPort().toString());
    				server.normalize();
    			}
    			
    			Element gpsdata = dom.createElement("gpsdata");
    			{
    				entry.appendChild(gpsdata);
    				{
    					Double[][] gpsArray = weather.getGpsData();
    					
    					gpsdata.setAttribute("longBase", gpsArray[0][0].toString());
    					gpsdata.setAttribute("latBase", gpsArray[0][1].toString());
    					
     					Element luv = dom.createElement("luv");
        				{
        					gpsdata.appendChild(luv);
        					luv.setAttribute("long1", gpsArray[1][0].toString());
        					luv.setAttribute("lat1", gpsArray[1][1].toString());
        					luv.normalize();
        				}
    					Element lee = dom.createElement("lee");
    					{
    						gpsdata.appendChild(lee);
    						lee.setAttribute("long1", gpsArray[2][0].toString());
    						lee.setAttribute("lat1", gpsArray[2][1].toString());
    						lee.setAttribute("long2", gpsArray[3][0].toString());
    						lee.setAttribute("lat2", gpsArray[3][1].toString());
    						lee.normalize();
    					}
    					Element fl = dom.createElement("finishLine");
    					{
    						gpsdata.appendChild(fl);
    						fl.setAttribute("long1", gpsArray[4][0].toString());
    						fl.setAttribute("lat1", gpsArray[4][1].toString());
    						fl.setAttribute("long2", gpsArray[5][0].toString());
    						fl.setAttribute("lat2", gpsArray[5][1].toString());
    						fl.normalize();
    					}
    					Element box = dom.createElement("startBox");
    					{
    						gpsdata.appendChild(box);
    						box.setAttribute("long1", gpsArray[6][0].toString());
    						box.setAttribute("lat1", gpsArray[6][1].toString());
    						box.setAttribute("long2", gpsArray[7][0].toString());
    						box.setAttribute("lat2", gpsArray[7][1].toString());
    						box.setAttribute("long3", gpsArray[8][0].toString());
    						box.setAttribute("lat3", gpsArray[8][1].toString());
    						box.setAttribute("long4", gpsArray[9][0].toString());
    						box.setAttribute("lat4", gpsArray[9][1].toString());
    						box.normalize();
    					}
    				}
    				gpsdata.normalize();
    			}
    			
    			Element winddata = dom.createElement("winddata");
    			{
    				entry.appendChild(winddata);
    				{
    					String[][] windArray = weather.getWindData();
    					
    					for (int j = 0; j < windArray.length; j++) {
    						Element wind = dom.createElement("wind");
        					{
        						winddata.appendChild(wind);
        						wind.setAttribute("strength", windArray[j][0]);
        						wind.setAttribute("direction", windArray[j][1]);
        						wind.setAttribute("fluctuation", windArray[j][2]);
        						wind.normalize();
        					}
						}
    					
    				}
    				winddata.normalize();
    			}
    			
    			entry.normalize();
    			
			}
    		
    		rootElement.normalize();
    		dom.normalize();

			Transformer transformer = TransformerFactory.newInstance().newTransformer();
			
			DOMSource        source = new DOMSource( dom );
			FileOutputStream os     = new FileOutputStream( new File(filename) );
			StreamResult     result = new StreamResult( os );
			transformer.transform( source, result );
			os.close();
			
			String line;
			StringBuffer sb = new StringBuffer();
			try
			{
				FileInputStream fis = new FileInputStream(filename);
				BufferedReader reader=new BufferedReader ( new InputStreamReader(fis));
				while((line = reader.readLine()) != null) {
					line = line.replaceAll("><", ">\n<");
					line = line.replaceAll("<entry", "\t<entry");
					line = line.replaceAll("</entry", "\t</entry");
					line = line.replaceAll("<se", "\t\t<se");
					line = line.replaceAll("<de", "\t\t<de");
					line = line.replaceAll("<gps", "\t\t<gps");
					line = line.replaceAll("</gps", "\t\t</gps");
					line = line.replaceAll("<l", "\t\t\t<l");
					line = line.replaceAll("<fi", "\t\t\t<fi");
					line = line.replaceAll("<st", "\t\t\t<st");
					line = line.replaceAll("<winddata", "\t\t<winddata");
					line = line.replaceAll("</winddata", "\t\t</winddata");
					line = line.replaceAll("<wind ", "\t\t\t<wind ");
					sb.append(line+"\n");}
				
				reader.close();
				BufferedWriter out=new BufferedWriter ( new FileWriter(filename));
				out.write(sb.toString());
				out.close();
			}
			catch (IOException e) {
				JOptionPane.showMessageDialog(new JFrame(),
						lng.get("dlg-sim-export-err") + "\n\nError: [IOException] " + e.getMessage(),
					    lng.get("dlg-sim-export"),
					    JOptionPane.WARNING_MESSAGE);
			}
			
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-export-ok"),
				    lng.get("dlg-sim-export"),
				    JOptionPane.INFORMATION_MESSAGE);
    		
	    }
		
		catch (IOException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-export-err") + "\n\nError: [IOException] " + e.getMessage(),
				    lng.get("dlg-sim-export"),
				    JOptionPane.WARNING_MESSAGE);
		} catch (ParserConfigurationException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-export-err") + "\n\nError: [ParserConfigurationException] " + e.getMessage(),
				    lng.get("dlg-sim-export"),
				    JOptionPane.WARNING_MESSAGE);
		} catch (Exception e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-sim-export-err") + "\n\nError: " + e.toString(),
				    lng.get("dlg-sim-export"),
				    JOptionPane.WARNING_MESSAGE);
		}

    }
}
